// Copyright (c) MatrixFramework. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Threading;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Matrix.ServiceCommunication.Options;

namespace Matrix.ServiceCommunication.Monitoring;

/// <summary>
/// 服务通信指标收集器
/// </summary>
public class ServiceCommunicationMetrics : IServiceCommunicationMetrics, IDisposable
{
    private readonly ILogger<ServiceCommunicationMetrics> _logger;
    private readonly IOptionsMonitor<MonitoringOptions> _options;
    private readonly Meter _meter;
    private readonly ActivitySource _activitySource;
    private bool _disposed;

    // HTTP请求指标
    private readonly Counter<int> _requestCounter;
    private readonly Histogram<double> _requestDuration;
    private readonly Counter<int> _errorCounter;
    private readonly ObservableGauge<int> _activeRequests;

    // 认证指标
    private readonly Counter<int> _authenticationSuccessCounter;
    private readonly Counter<int> _authenticationFailureCounter;

    // 服务发现指标
    private readonly Counter<int> _serviceDiscoveryOperationCounter;
    private readonly Histogram<double> _serviceDiscoveryDuration;

    // 容错策略指标
    private readonly Counter<int> _resilienceStrategyCounter;

    // 内部状态跟踪
    private readonly ConcurrentDictionary<string, int> _activeRequestsByService;

    public ServiceCommunicationMetrics(
        ILogger<ServiceCommunicationMetrics> logger,
        IOptionsMonitor<MonitoringOptions> options)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        _options = options ?? throw new ArgumentNullException(nameof(options));

        var monitoringOptions = options.CurrentValue;
        _meter = new Meter(monitoringOptions.ServiceName, "1.0.0");
        _activitySource = new ActivitySource(monitoringOptions.ServiceName);

        _activeRequestsByService = new ConcurrentDictionary<string, int>();

        // 创建HTTP请求指标
        _requestCounter = _meter.CreateCounter<int>(
            "http_requests_total",
            description: "HTTP请求总数");

        _requestDuration = _meter.CreateHistogram<double>(
            "http_request_duration_seconds",
            description: "HTTP请求持续时间（秒）",
            unit: "s");

        _errorCounter = _meter.CreateCounter<int>(
            "http_requests_errors_total",
            description: "HTTP请求错误总数");

        _activeRequests = _meter.CreateObservableGauge(
            "http_requests_active",
            () => _activeRequestsByService.Values.Sum(),
            description: "当前活跃的HTTP请求数");

        // 创建认证指标
        _authenticationSuccessCounter = _meter.CreateCounter<int>(
            "authentication_success_total",
            description: "认证成功总数");

        _authenticationFailureCounter = _meter.CreateCounter<int>(
            "authentication_failure_total",
            description: "认证失败总数");

        // 创建服务发现指标
        _serviceDiscoveryOperationCounter = _meter.CreateCounter<int>(
            "service_discovery_operations_total",
            description: "服务发现操作总数");

        _serviceDiscoveryDuration = _meter.CreateHistogram<double>(
            "service_discovery_duration_seconds",
            description: "服务发现操作持续时间（秒）",
            unit: "s");

        // 创建容错策略指标
        _resilienceStrategyCounter = _meter.CreateCounter<int>(
            "resilience_strategy_executions_total",
            description: "容错策略执行总数");

        // 订阅配置变更
        _options.OnChange(OnConfigurationChanged);

        _logger.LogInformation("服务通信指标收集器已初始化，服务名称: {ServiceName}",
            monitoringOptions.ServiceName);
    }

    public void RecordRequest(string serviceName, string method, int statusCode, double duration)
    {
        if (!_options.CurrentValue.EnableMetrics) return;

        var tags = new TagList
        {
            { "service.name", serviceName },
            { "http.method", method },
            { "http.status_code", statusCode.ToString() },
            { "http.status_class", GetStatusClass(statusCode) }
        };

        // 记录请求总数
        _requestCounter.Add(1, tags);

        // 记录请求持续时间（转换为秒）
        _requestDuration.Record(duration / 1000.0, tags);

        // 记录错误请求
        if (statusCode >= 400)
        {
            _errorCounter.Add(1, tags);
        }

        // 记录到日志
        _logger.LogDebug("记录HTTP请求指标: {ServiceName} {Method} {StatusCode} {Duration}ms",
            serviceName, method, statusCode, duration);
    }

    public void IncrementActiveRequests(string serviceName)
    {
        if (!_options.CurrentValue.EnableMetrics) return;

        _activeRequestsByService.AddOrUpdate(serviceName, 1, (_, value) => value + 1);

        _logger.LogDebug("增加活跃请求计数: {ServiceName}, 当前活跃数: {Count}",
            serviceName, _activeRequestsByService[serviceName]);
    }

    public void DecrementActiveRequests(string serviceName)
    {
        if (!_options.CurrentValue.EnableMetrics) return;

        _activeRequestsByService.AddOrUpdate(serviceName, 0, (_, value) => Math.Max(0, value - 1));

        _logger.LogDebug("减少活跃请求计数: {ServiceName}, 当前活跃数: {Count}",
            serviceName, _activeRequestsByService[serviceName]);
    }

    public void RecordAuthenticationSuccess(string authType, string serviceName)
    {
        if (!_options.CurrentValue.EnableMetrics) return;

        var tags = new TagList
        {
            { "auth.type", authType },
            { "service.name", serviceName }
        };

        _authenticationSuccessCounter.Add(1, tags);

        _logger.LogDebug("记录认证成功: {AuthType} -> {ServiceName}", authType, serviceName);
    }

    public void RecordAuthenticationFailure(string authType, string serviceName, string errorType)
    {
        if (!_options.CurrentValue.EnableMetrics) return;

        var tags = new TagList
        {
            { "auth.type", authType },
            { "service.name", serviceName },
            { "error.type", errorType }
        };

        _authenticationFailureCounter.Add(1, tags);

        _logger.LogWarning("记录认证失败: {AuthType} -> {ServiceName}, 错误类型: {ErrorType}",
            authType, serviceName, errorType);
    }

    public void RecordServiceDiscoveryOperation(string operation, string serviceName, bool success, double duration)
    {
        if (!_options.CurrentValue.EnableMetrics) return;

        var tags = new TagList
        {
            { "operation.type", operation },
            { "service.name", serviceName },
            { "success", success.ToString() }
        };

        _serviceDiscoveryOperationCounter.Add(1, tags);
        _serviceDiscoveryDuration.Record(duration / 1000.0, tags);

        _logger.LogDebug("记录服务发现操作: {Operation} {ServiceName} {Success} {Duration}ms",
            operation, serviceName, success, duration);
    }

    public void RecordResilienceStrategy(string strategy, string serviceName, bool success)
    {
        if (!_options.CurrentValue.EnableMetrics) return;

        var tags = new TagList
        {
            { "strategy.type", strategy },
            { "service.name", serviceName },
            { "success", success.ToString() }
        };

        _resilienceStrategyCounter.Add(1, tags);

        _logger.LogDebug("记录容错策略执行: {Strategy} {ServiceName} {Success}",
            strategy, serviceName, success);
    }

    /// <summary>
    /// 开始一个新的Activity用于链路追踪
    /// </summary>
    /// <param name="activityName">活动名称</param>
    /// <param name="serviceName">服务名称</param>
    /// <param name="operationName">操作名称</param>
    /// <returns>Activity实例</returns>
    public Activity? StartActivity(string activityName, string serviceName, string operationName)
    {
        if (!_options.CurrentValue.EnableTracing) return null;

        var tags = new ActivityTagsCollection
        {
            { "service.name", serviceName },
            { "operation.name", operationName },
            { "library.name", "Matrix.ServiceCommunication" }
        };

        return _activitySource.StartActivity(activityName, ActivityKind.Client, tags: tags);
    }

    /// <summary>
    /// 设置Activity标签
    /// </summary>
    /// <param name="activity">Activity实例</param>
    /// <param name="tags">标签字典</param>
    public void SetActivityTags(Activity? activity, params (string key, string value)[] tags)
    {
        if (activity == null || !_options.CurrentValue.EnableTracing) return;

        foreach (var (key, value) in tags)
        {
            activity.SetTag(key, value);
        }
    }

    private static string GetStatusClass(int statusCode)
    {
        return statusCode switch
        {
            >= 200 and < 300 => "2xx",
            >= 300 and < 400 => "3xx",
            >= 400 and < 500 => "4xx",
            >= 500 => "5xx",
            _ => "unknown"
        };
    }

    private void OnConfigurationChanged(MonitoringOptions newOptions)
    {
        _logger.LogInformation("监控配置已变更，启用指标: {EnableMetrics}, 启用链路追踪: {EnableTracing}",
            newOptions.EnableMetrics, newOptions.EnableTracing);
    }

    public void Dispose()
    {
        if (_disposed) return;

        _disposed = true;
        _meter?.Dispose();
        _activitySource?.Dispose();

        _logger.LogDebug("服务通信指标收集器已释放");
    }
}